package client.presentation;

import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.Geometry;
import javax.media.j3d.Locale;
import javax.media.j3d.PhysicalBody;
import javax.media.j3d.PhysicalEnvironment;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.media.j3d.View;
import javax.media.j3d.ViewPlatform;
import javax.media.j3d.VirtualUniverse;

import org.jdesktop.j3d.loaders.vrml97.VrmlLoader;

import client.controller.Universe3DController;

import com.sun.j3d.loaders.Scene;
import com.sun.j3d.utils.picking.PickCanvas;
import com.sun.j3d.utils.universe.SimpleUniverse;
import com.sun.j3d.utils.universe.ViewingPlatform;

//Classe mettant en oeuvre la representation 3D du monde. On peut y ajouter des objets 3D
public class Universe3DPresentation{

	private static final long serialVersionUID = -474753382040258485L;
	
	private Universe3DController controller = null;
	private VirtualUniverse virtualUniverse = null;
	private ViewingPlatform viewingPlatform = null;
	private Canvas3D canvas = null;
	private BranchGroup scene = null;
	private PickCanvas pickCanvas = null;
	
	public Universe3DPresentation (Universe3DController c) {
		controller = c;
		
		viewingPlatform = new ViewingPlatform();
		
		canvas = new Canvas3D(SimpleUniverse.getPreferredConfiguration());

		virtualUniverse = new VirtualUniverse();
		Locale locale = new Locale(virtualUniverse);
		ViewPlatform viewPlateform = new ViewPlatform();
		PhysicalBody physicalBody = new PhysicalBody();
		PhysicalEnvironment physicalEnvironnement = new PhysicalEnvironment();
		View view = new View();
		view.addCanvas3D(canvas);
		view.setPhysicalBody(physicalBody);
		view.setPhysicalEnvironment(physicalEnvironnement);
		view.attachViewPlatform(viewPlateform);
		((ViewingPlatform)viewingPlatform).setViewPlatform(viewPlateform);
		TransformGroup viewPointTransform = ((ViewingPlatform)viewingPlatform).getViewPlatformTransform();
		viewPointTransform.setCapability(TransformGroup.ALLOW_TRANSFORM_READ) ;
		viewPointTransform.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE) ;
		viewPointTransform.setCapability(TransformGroup.ALLOW_CHILDREN_READ);
		viewPointTransform.setCapability(TransformGroup.ALLOW_CHILDREN_WRITE);
		viewPointTransform.setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND);

		((ViewingPlatform)viewingPlatform).compile();

		scene = new BranchGroup();
		scene.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
		scene.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
		scene.setCapability(BranchGroup.ALLOW_CHILDREN_READ);
		scene.setCapability(BranchGroup.ALLOW_PICKABLE_READ);
		scene.setCapability(BranchGroup.ALLOW_PICKABLE_WRITE);
		
		Transform3D viewPointTransform3D = new Transform3D();
		viewPointTransform.getTransform(viewPointTransform3D);
		
		VrmlLoader loader = new VrmlLoader () ;
		
		Scene lumiereScene;
		try {
			lumiereScene = loader.load ("vrml/lumiere.wrl");
			TransformGroup group = new TransformGroup();
			group.addChild(lumiereScene.getSceneGroup());
			scene.addChild(group);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		scene.compile();
	
		locale.addBranchGraph((ViewingPlatform)viewingPlatform);
		locale.addBranchGraph(scene);
		
		pickCanvas = new PickCanvas(canvas, scene);
	}
	
	public ViewingPlatform getViewingPlatform() {
		return viewingPlatform;
	}
	
	public Canvas3D getCanvas() {
		return canvas;
	}
	
	public PickCanvas getPickCanvas() {
		return pickCanvas;
	}
	
	public BranchGroup getScene() {
		return scene;
	}
	
	public void addObject(Object3DPresentation object) {
		((TransformGroup)object).setCapability(Geometry.ALLOW_INTERSECT);
		BranchGroup branch = new BranchGroup();
		branch.setCapability(TransformGroup.ALLOW_TRANSFORM_READ) ;
		branch.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE) ;
		branch.setCapability(TransformGroup.ENABLE_PICK_REPORTING) ;
		branch.setCapability(Geometry.ALLOW_INTERSECT);
		branch.addChild((TransformGroup)object);
		scene.addChild(branch);
	}
}
